#coding:utf-8
from pymongo import MongoClient
from pythonems.settings import MONGO_DATABASES
from bson.objectid import ObjectId
import copy

class IMongo(object):
    __collection__ = 'question'
    __database__ = MONGO_DATABASES["name"]
    structure = {
        "id": int,
    }
    required_fields = ['id']
    default_values = {}
    relation_dict = {
        "id": "pk",
    }
    @classmethod
    def get_collection(cls):
        database_name = cls.__database__
        collection_name = cls.__collection__
        client = MongoClient(MONGO_DATABASES["host"], MONGO_DATABASES["port"])
        return client[database_name][collection_name]
    @classmethod
    def validating(cls, kwargs):
        for key, value in kwargs.iteritems():
            if not cls.structure.has_key(key):
                raise Exception('The "{key}" part is not needed.'.format(
                    key=key,
                ))
            if not isinstance(value, cls.structure[key]):
                raise Exception('The "{key}" part, {value}, shoule be {iformat}'.format(
                    key=key,
                    value=value,
                    iformat=str(cls.structure[key])
                ))
        return True
    @classmethod
    def valid_required(cls, kwargs):
        for index in range(len(cls.required_fields)):
            item = cls.required_fields[index]
            if not kwargs.has_key(item):
                raise Exception('The "{key}" part is required field of this collection.'.format(
                                    key=item,
                                ))
        return True
    @classmethod
    def create(cls, kwargs):
        collection = cls.get_collection()
        create_kwargs = copy.copy(cls.default_values)
        create_kwargs.update(kwargs)
        if cls.validating(create_kwargs) and cls.valid_required(create_kwargs):
            return collection.insert(create_kwargs)
    @classmethod
    def update(cls, item_pk, kwargs):
        collection = cls.get_collection()
        if cls.validating(kwargs):
            if isinstance(item_pk, ObjectId):
                return collection.update({"_id": item_pk}, {"$set":kwargs})
            else:
                return collection.update({"id": item_pk}, {"$set":kwargs})
    @classmethod
    def search(cls, id_list):
        collection = cls.get_collection()
        if isinstance(id_list[0], ObjectId):        
            return collection.find({"_id": {"$in": id_list}})
        else:
            return collection.find({"id": {"$in": id_list}})